package com.ddstation.crm.menu.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ddstation.crm.institution.mapper.DtHealthManageInstitutionDoctorMapper;
import com.ddstation.crm.institution.mapper.DtHealthManageInstitutionMapper;
import com.ddstation.crm.menu.entity.DtHealthManageInstitutionMenuCustomizeEntity;
import com.ddstation.crm.menu.entity.DtInvsManageInstitutionMenuEntity;
import com.ddstation.crm.menu.entity.DtInvsManageInstitutionMenuMinusEntity;
import com.ddstation.crm.menu.entity.DtInvsManageInstitutionMenuPanelEntity;
import com.ddstation.crm.menu.mapper.DtHealthManageInstitutionMenuCustomizeMapper;
import com.ddstation.crm.menu.mapper.DtInvsManageInstitutionMenuMapper;
import com.ddstation.crm.menu.mapper.DtInvsManageInstitutionMenuMinusMapper;
import com.ddstation.crm.menu.mapper.DtInvsManageInstitutionMenuPanelMapper;

@Service
public class MenuServiceImpl implements MenuService {

	@Override
	@Transactional(readOnly=true)
	public List<DtInvsManageInstitutionMenuEntity> getSecondMenus(List<DtInvsManageInstitutionMenuEntity> menus,String firstMenuUrl) {
		for(DtInvsManageInstitutionMenuEntity menu:menus){
			if(firstMenuUrl.equals(menu.getUrl())){
				//取目标一级菜单下的目录
				List<DtInvsManageInstitutionMenuEntity> secondMenus = menu.getChildrens();
				if(secondMenus == null){
					//存在一级目录但是无二级目录则返回空数组
					secondMenus = new ArrayList<>();
				}
				return secondMenus;
			}
		}
		//返回null表示无访问权限
		return null;
	}
	
	@Override
	@Transactional(readOnly=true)
	public List<DtInvsManageInstitutionMenuPanelEntity> getPanelMenu() {
		// TODO Auto-generated method stub
		return dtInvsManageInstitutionMenuPanelMapper.selectList();
	}

	@Override
	@Transactional(readOnly=true)
	public List<DtInvsManageInstitutionMenuEntity> getVerticalMenu(String institutionId, int doctorId, Byte authType, MENU_FILTER_ENUM filterLevel) {
		// 根据doctor的权限 做成菜单
		List<Integer> authTypeArray = this.getAccessableAuthType(4);
		List<DtInvsManageInstitutionMenuEntity> menuEntities = dtInvsManageInstitutionMenuMapper.select(institutionId, doctorId, authTypeArray); // get menu data
		if (menuEntities == null || menuEntities.isEmpty()) {
			return null;
			//throw new IllegalStateException("《卫监》 没有菜单数据");
		} else {
			// 页面显示menu tree
			List<DtInvsManageInstitutionMenuEntity> menus = new ArrayList<DtInvsManageInstitutionMenuEntity>();
			Iterator<DtInvsManageInstitutionMenuEntity> ite = menuEntities.iterator();// 遍历数据库中取到的menu data
			// 做成1级菜单
			while (ite.hasNext()) {
				DtInvsManageInstitutionMenuEntity each = ite.next();
				// 筛选1级菜单
				if (each.getParent() == null) { // p_menu_id null为1级菜单项目
					menus.add(each);
					ite.remove();
				}
			}

			if (menus.isEmpty()) { // 没有1级菜单项目为异常
				throw new IllegalStateException("《卫监》 没有1级菜单数据（p_menu_id is null）");
			} else {
				boolean loop = false;
				do {
					loop = false;

					ite = menuEntities.iterator(); // 遍历 剩余menu
					while (ite.hasNext()) {
						DtInvsManageInstitutionMenuEntity menu = ite.next();
						DtInvsManageInstitutionMenuEntity p = this.findParent(menu, menus);
						if (p != null) {
							if (p.getChildrens() == null) {
								p.setChildrens(new ArrayList<DtInvsManageInstitutionMenuEntity>());
							}
							p.getChildrens().add(menu);
							ite.remove();
							loop = true;
						}
					}
				} while (loop);
			}
			return menus;
		}
	}

	@Override
	@Transactional(readOnly=true)
	public List<DtInvsManageInstitutionMenuEntity> getWorkbenchVerticalMenu() {
		List<DtInvsManageInstitutionMenuEntity> menuEntities = dtInvsManageInstitutionMenuMapper.workbenchSelect();
		if (menuEntities == null || menuEntities.isEmpty()) {
			return null;
			//throw new IllegalStateException("《卫监》 没有菜单数据");
		} else {
			// 页面显示menu tree
			List<DtInvsManageInstitutionMenuEntity> menus = new ArrayList<DtInvsManageInstitutionMenuEntity>();
			Iterator<DtInvsManageInstitutionMenuEntity> ite = menuEntities.iterator();// 遍历数据库中取到的menu data
			// 做成1级菜单
			while (ite.hasNext()) {
				DtInvsManageInstitutionMenuEntity each = ite.next();
				// 筛选1级菜单
				if (each.getParent() == null) { // p_menu_id null为1级菜单项目
					if (!(each.getUrl()).equals("invs_statistics_statement.do")) {
						menus.add(each);
					}
					ite.remove();
				}
			}

			if (menus.isEmpty()) { // 没有1级菜单项目为异常
				throw new IllegalStateException("《卫监》 没有1级菜单数据（p_menu_id is null）");
			} else {
				boolean loop = false;
				do {
					loop = false;

					ite = menuEntities.iterator(); // 遍历 剩余menu
					while (ite.hasNext()) {
						DtInvsManageInstitutionMenuEntity menu = ite.next();
						DtInvsManageInstitutionMenuEntity p = this.findParent(menu, menus);
						if (p != null) {
							if (p.getChildrens() == null) {
								p.setChildrens(new ArrayList<DtInvsManageInstitutionMenuEntity>());
							}
							p.getChildrens().add(menu);
							ite.remove();
							loop = true;
						}
					}
				} while (loop);
			}
			return menus;
		}
	}
	
	/**
	 * 寻找父节点
	 * @param baby
	 * @param persons
	 * @return
	 */
	private DtInvsManageInstitutionMenuEntity findParent(DtInvsManageInstitutionMenuEntity baby, List<DtInvsManageInstitutionMenuEntity> persons) {
		for (DtInvsManageInstitutionMenuEntity p : persons) {
			if (baby.getParent().getId().intValue() == p.getId().intValue()) {
				return p;
			} else {
				if (p.getChildrens() != null && !p.getChildrens().isEmpty()) {
					DtInvsManageInstitutionMenuEntity _p = findParent(baby, p.getChildrens());
					if (_p != null) {
						return _p;
					}
				}
			}
		}
		return null;
	}
	
	@Override
	@Transactional(readOnly=true)
	public List<DtInvsManageInstitutionMenuEntity> getHorizontalMenu(String institutionId, int doctorId, MENU_FILTER_ENUM filterLevel) {
		// TODO Auto-generated method stub
		// 根据doctor的权限 做成菜单
		List<Integer> authTypeArray = this.getAccessableAuthType(4);
		List<DtInvsManageInstitutionMenuEntity> menuEntities = dtInvsManageInstitutionMenuMapper.selectHorizontal(institutionId, doctorId, authTypeArray); // get menu data
		if (menuEntities == null || menuEntities.isEmpty()) {
			throw new IllegalStateException("《卫监》 没有菜单数据");
		} else {
			// 页面显示menu tree
			List<DtInvsManageInstitutionMenuEntity> menus = new ArrayList<DtInvsManageInstitutionMenuEntity>();
			Iterator<DtInvsManageInstitutionMenuEntity> ite = menuEntities.iterator();// 遍历数据库中取到的menu data
			// 做成1级菜单
			while (ite.hasNext()) {
				DtInvsManageInstitutionMenuEntity each = ite.next();
				// 筛选1级菜单
				if (each.getParent() == null) { // p_menu_id null为1级菜单项目
					menus.add(each);
					ite.remove();
				}
			}

			if (menus.isEmpty()) { // 没有1级菜单项目为异常
				throw new IllegalStateException("《卫监》 没有1级菜单数据（p_menu_id is null）");
			} else {
				boolean loop = false;
				do {
					loop = false;

					ite = menuEntities.iterator(); // 遍历 剩余menu
					while (ite.hasNext()) {
						DtInvsManageInstitutionMenuEntity menu = ite.next();
						DtInvsManageInstitutionMenuEntity p = this.findParent(menu, menus);
						if (p != null) {
							if (p.getChildrens() == null) {
								p.setChildrens(new ArrayList<DtInvsManageInstitutionMenuEntity>());
							}
							p.getChildrens().add(menu);
							ite.remove();
							loop = true;
						}
					}
				} while (loop);
			}
			return menus;
		}
	}

	
	@Override
	@Transactional(readOnly=true)
	public List<DtInvsManageInstitutionMenuEntity> initDoctorVerticalMenuSetting(String institutionId, int doctorId) {
		// TODO Auto-generated method stub
		List<DtInvsManageInstitutionMenuEntity> menus = this.getHorizontalMenu(institutionId, doctorId, MENU_FILTER_ENUM.INSTITUTION);
		return this.filterDoctor(institutionId, doctorId, menus, this.VERTICAL_MENU_TYPE, false);
	}
	
	@Override
	@Transactional(rollbackFor=Exception.class)
	public void saveDoctorVerticalMenuSetting(String institutionId, int doctorId, Integer[]minusMenus) {
		// TODO Auto-generated method stub
		dtInvsManageInstitutionMenuMinusMapper.delete(institutionId, doctorId, this.VERTICAL_MENU_TYPE);
		if (minusMenus != null && minusMenus.length > 0) {
			dtInvsManageInstitutionMenuMinusMapper.insert(institutionId,0 , doctorId, null, this.VERTICAL_MENU_TYPE);
		}
	}
	
	@Override
	@Transactional(readOnly=true)
	public List<DtInvsManageInstitutionMenuEntity> intDoctorHorizontalMenuSetting(String institutionId, int doctorId) {
		// TODO Auto-generated method stub
		List<DtInvsManageInstitutionMenuEntity> menus = this.getHorizontalMenu(institutionId, doctorId, MENU_FILTER_ENUM.INSTITUTION);
		return this.filterDoctor(institutionId, doctorId, menus, this.HORIZONTAL_MENU_TYPE, false);
	}
	
	@Override
	@Transactional(rollbackFor=Exception.class)
	public void saveDoctorHorizontalMenuSetting(String institutionId, int doctorId, Integer[]minusMenus) {
		// TODO Auto-generated method stub
		dtInvsManageInstitutionMenuMinusMapper.delete(institutionId, doctorId, this.HORIZONTAL_MENU_TYPE);
		if (minusMenus != null && minusMenus.length > 0) {
			dtInvsManageInstitutionMenuMinusMapper.insert(institutionId, 0 ,doctorId, null, this.HORIZONTAL_MENU_TYPE);
		}
	}

	/**
	 * 自定义菜单 适用
	 * @param institutionId
	 * @param menus
	 */
	private List<DtInvsManageInstitutionMenuEntity> filterInstitution(String institutionId, List<DtInvsManageInstitutionMenuEntity> menus, int menuType, boolean onlyVisibility) {
		// 菜单自定义应用
		List<DtHealthManageInstitutionMenuCustomizeEntity> customizesRules = dtInvsManageInstitutionMenuCustomizeMapper.select(institutionId, menuType);
		if (customizesRules != null && !customizesRules.isEmpty()) {
			// 根据 菜单自定义 调整显示菜单（位置，名称等）
//			List<DtInvsManageInstitutionMenuEntity> customizesMenus = new ArrayList<DtInvsManageInstitutionMenuEntity>(menus.size());
			for (DtHealthManageInstitutionMenuCustomizeEntity r : customizesRules) {// 遍历自定义规则
				menus = this.doFilterInstitution(r, menus, onlyVisibility);
			}
		}
		return menus;
	}
	private List<DtInvsManageInstitutionMenuEntity> doFilterInstitution(DtHealthManageInstitutionMenuCustomizeEntity r, List<DtInvsManageInstitutionMenuEntity> menus, boolean onlyVisibility) {
		for (DtInvsManageInstitutionMenuEntity _m : menus) {// 遍历显示菜单（问暖规则）
			if (r.getMenuId().intValue() == _m.getId().intValue()) {// 匹配菜单
				_m.setName(r.getName());
				_m.setVisibility(r.getVisibility());
				_m.setOrderNb(r.getOrderNb());
				if (onlyVisibility && r.getVisibility() == 0) {
					menus.remove(_m);
					break;
				}
			} else if (_m.getChildrens() != null) {
				_m.setChildrens(this.doFilterInstitution(r, _m.getChildrens(), onlyVisibility));
			}
		}
		// 菜单排序
		Collections.sort(menus, new MyTaskComparator());
		return menus;
	}
	
	
	
	/**
	 * 用户权限限制
	 * 注意：： 必须在menu tree结构做成前使用（未做成2级菜单前）
	 * @param institutionId
	 * @param doctorId
	 * @param menus
	 * @param menuType
	 * @return
	 */
	private List<DtInvsManageInstitutionMenuEntity> filterDoctor(String institutionId, int doctorId, List<DtInvsManageInstitutionMenuEntity> menus, int menuType, boolean onlyVisibility) {
		if (menus == null) {
			return null;
		} else {
			List<DtInvsManageInstitutionMenuMinusEntity> minusMenus = dtInvsManageInstitutionMenuMinusMapper.select(institutionId, doctorId, menuType);
			return this.doFilterDoctor(menus, minusMenus, onlyVisibility);
		}
	}
	
	
	/**
	 * 递归过滤 用户菜单使用限制
	 * @param menus
	 * @param minusMenus
	 * @return
	 */
	private List<DtInvsManageInstitutionMenuEntity> doFilterDoctor(List<DtInvsManageInstitutionMenuEntity> menus, List<DtInvsManageInstitutionMenuMinusEntity> minusMenus, boolean onlyVisibility) {
		if (menus == null || menus.isEmpty()) {
			return menus;
		} else if (minusMenus == null || minusMenus.isEmpty()) {
			return menus;
		} else {
			Iterator<DtInvsManageInstitutionMenuEntity> menusIter = menus.iterator();
			while (menusIter.hasNext()) {
				DtInvsManageInstitutionMenuEntity menu = menusIter.next();
				for (DtInvsManageInstitutionMenuMinusEntity minusMenu : minusMenus) {
					if (menu.getId().intValue() == minusMenu.getMenuId().intValue()) {
						if (onlyVisibility) {
							menusIter.remove();
						} else {
							menu.setVisibility(0); // 不可见
						}
						break;
					}
				}
				
				// 递归过滤
				if (menu.getChildrens() != null && !menu.getChildrens().isEmpty()) {
					this.doFilterDoctor(menu.getChildrens(), minusMenus, onlyVisibility);
				}
			}
			return menus;
		}
	}
	
	/**
	 * 只能使用基础功能（105，110等账号过期时）
	 * @param menus
	 * @param menuType
	 * @return
	 */
	private List<DtInvsManageInstitutionMenuEntity> onlyBaseMenu(List<DtInvsManageInstitutionMenuEntity> menus, int menuType) {
//		if (menus != null && !menus.isEmpty()) {
//			List<DtInvsManageAccounttypeMenuEntity> baseMenus = dtHealthManageAccounttypeMenuMapper.select(ConstAccountType.BASE, menuType);
//			if (baseMenus != null && !baseMenus.isEmpty()) {
//				for (DtInvsManageInstitutionMenuEntity menu : menus) {
//					this.matchBaseMenu(menu, baseMenus);
//				}
//			}
//		}
		return null;
	}
//	private void matchBaseMenu(DtInvsManageInstitutionMenuEntity menu, List<DtInvsManageAccounttypeMenuEntity> baseMenus) {
//		boolean matched = false;
//		for (DtInvsManageAccounttypeMenuEntity _m : baseMenus) {
//			if (_m.getMenuId().intValue() == menu.getId().intValue()) {
//				matched = true;
//				break;
//			}
//		}
//		if (!matched) { // 非基础菜单，不可使用
//			menu.setAvailable(false);
//			menu.setUrl(null);
//		}
//		if (menu.getChildrens() != null) {
//			for (DtInvsManageInstitutionMenuEntity _cm : menu.getChildrens()) {
//				this.matchBaseMenu(_cm, baseMenus);
//			}
//		}
//	}
	
	/**
	 * linux 1、2、4权限规则
	 * @param authType
	 * @return
	 */
	private List<Integer> getAccessableAuthType(int authType) {
		List<Integer> authTypeArray = new ArrayList<Integer>();
		switch (authType) { // linux 1，2，4权限规则
		case 1:
			authTypeArray.add(1); // 1
			authTypeArray.add(3); // 1 + 2
			authTypeArray.add(5); // 1 + 4
			authTypeArray.add(7); // 1 + 2 + 4
			break;
		case 2:
			authTypeArray.add(2); // 2
			authTypeArray.add(3); // 1 + 2
			authTypeArray.add(6); // 2 + 4
			authTypeArray.add(7); // 1 + 2 + 4
			break;
		case 4:
			authTypeArray.add(4); // 4
			authTypeArray.add(5); // 1 + 4
			authTypeArray.add(6); // 2 + 4
			authTypeArray.add(7); // 1 + 2 + 4
			break;
		default:
			throw new IllegalArgumentException("用户权限必须是1 or 2 or 4。  authType=" + authType);
		}
		return authTypeArray;
	}
	
	private final int VERTICAL_MENU_TYPE = 1;
	private final int HORIZONTAL_MENU_TYPE = 2;
	private @Inject DtHealthManageInstitutionMapper dtHealthManageInstitutionMapper = null;
	private @Inject DtHealthManageInstitutionDoctorMapper dtHealthManageInstitutionDoctorMapper = null;
	private @Inject
    DtInvsManageInstitutionMenuMapper dtInvsManageInstitutionMenuMapper = null;
	private @Inject
	DtHealthManageInstitutionMenuCustomizeMapper dtInvsManageInstitutionMenuCustomizeMapper = null;
	private @Inject
	DtInvsManageInstitutionMenuMinusMapper dtInvsManageInstitutionMenuMinusMapper = null;
	private @Inject
	DtInvsManageInstitutionMenuPanelMapper dtInvsManageInstitutionMenuPanelMapper = null;
//	private @Inject DtInvsManageAccounttypeMenuMapper dtInvsManageAccounttypeMenuMapper = null;
}

class MyTaskComparator implements Comparator<DtInvsManageInstitutionMenuEntity> {
	public final static int UP = -1;
	public final static int DOWN = 1;
	
	public int compare(DtInvsManageInstitutionMenuEntity o1, DtInvsManageInstitutionMenuEntity o2) {
		if(null != o1 && null != o2) {
			
			int t1 = o1.getOrderNb() == null ? 0 : o1.getOrderNb();
			int t2 = o2.getOrderNb() == null ? 0 : o2.getOrderNb();
			if(t1 >= t2)
				return MyTaskComparator.DOWN;
			else
				return MyTaskComparator.UP;
		} else {
			throw new RuntimeException("比较对象有null");
		}
	}
}